# -*- coding: UTF-8 -*-
# 关于时间转换的小工具

import os
import sys
import datetime
import math

# datetime 转 公历时间 
def datetime2cal(dateT):
    return [dateT.year, dateT.month, dateT.day, dateT.hour, dateT.minute, dateT.second, dateT.microsecond] 


# 公历时间 转 datetime  
def cal2datetime(cal):
    return datetime.datetime(cal[0],cal[1],cal[2],cal[3],cal[4],cal[5],cal[6])


# 公历时间 转 简化儒略日  
def cal2mjd(cal):
    if(len(cal)<6):
        for i in range(len(cal),6):
            cal.append(0)
    year  = cal[0]
    month = cal[1]
    day   = cal[2]+(cal[3]*3600+cal[4]*60+cal[5]+18+cal[6]*1e-6)/86400
    y     = year+4800  
    m     = month
    if( year < 0 ):
        print('Year is wrong')
        return False
    
    if( m <= 2):
        m = m + 12
        y = y - 1
    e = math.floor(30.6 * (m+1))
    a = math.floor(y/100)
    if( year <1582 )or(year==1582 and month<10)or(year==1582 and month==10 and day<15):
        b = -38
    else:
        b = math.floor((a/4) - a)
    c = math.floor(365.25 * y)
    jd = b + c + e + day - 32167.5
    mjd = jd - 2400000.5
    return mjd
 

# 简化儒略日 转 公历时间
def mjd2cal(mjd):
    J = mjd + 2400000.5
    if (J < 1721423.5):
        BC = 1
    else:
        BC = 0
 
    if( J < 2299160.5 ): 
        j0=math.floor(J+0.5)
        dd=J+0.5-j0
    else: 
        n1=math.floor((J-2342031.5)/36524.25/4)+1   #1700.3.1.0
        n2=math.floor((J-2378555.5)/36524.25/4)+1   #1800.3.1.0
        n3=math.floor((J-2415079.5)/36524.25/4)+1   #1900.3.1.0
        j0=n1+n2+n3+J+10
        dd=j0+0.5-math.floor(j0+0.5)
        j0=math.floor(j0+0.5)
    
    j0=j0+32083
    year0=math.ceil(j0/365.25)-1
    year=year0-4800
    day=j0-math.floor(year0*365.25)
    month=math.floor((day-0.6)/30.6)+3
    day=day-round((month-3)*30.6)
    
    if (month>12):
        month=month-12
        year=year+1    
    year=year-BC
    sec=math.floor(dd*86400)    
    microsecond = (dd*86400 - sec) * 1e6
    hour=math.floor(sec/3600)
    sec=sec-hour*3600
    minute=math.floor(sec/60)
    sec=sec-minute*60  
    return [int(year), int(month), int(day), int(hour), int(minute), int(sec), int(microsecond)]


# 公历时间字符串 转 datetime
def str2time(strTime):
    # str format："2020  3 29  0  0  0[.000000]" []表示可有可无
    if len(strTime)>20:#暂时未用到
        msec=int(float('0.'+strTime[20:])*1000000) #微秒
    str2=strTime[0:19]+' '+str(msec)
    return datetime.datetime.strptime(str2,'%Y %m %d %H %M %S %f')
    

# datetime 转 简化儒略日
def datetime2mjd(dateT):
    t0=datetime.datetime(1858,11,17,0,0,0,0) #简化儒略日起始日
    mjd=(dateT-t0).days
    mjd_s=dateT.hour*3600.0+dateT.minute*60.0+dateT.second+dateT.microsecond/1000000.0
    return mjd+mjd_s/86400.0


# 简化儒略日 转 datetime
def mjd2datetime(mjd):
    t0=datetime.datetime(1858,11,17,0,0,0,0) #简化儒略日起始日
    return t0+datetime.timedelta(days=mjd)


# 简化儒略日 转 儒略日
def mjd2jd(mjd):
    return mjd+2400000.5


# 儒略日 转 简化儒略日
def jd2mjd(jd):
    return jd-2400000.5


# 公历时间 转 GPS周和周内秒
def cal2gps(cal):
    # 返回列表，周和周内秒
    mjd=cal2mjd(cal)
    #GPS从MJD44244开始
    e=mjd-44244
    week=math.floor(e/7)
    e=e-week*7            
    return [week,round(e*86400)]
 
 
# GPS周和周内秒 转 公历时间
def gps2cal(gps):
    # 返回列表 年月日时分秒
    # GPS从MJD44244开始
    mjd = 44244+(gps[0]*86400*7+gps[1]-18)/86400
    cal = mjd2cal(mjd)
    return cal


# 公历时间 转 Unix timestamp(ns)
def cal2timestamp(cal):
    utc_time = datetime.datetime(cal[0], cal[1], cal[2], cal[3], cal[4], cal[5], cal[6])
    # print (utc_time.timestamp())
    timestamp = int(utc_time.timestamp() * 1e9)
    return timestamp


# datetime 转 Unix timestamp(ns)
def datetime2timestamp(dateT):
    timestamp = int(dateT.timestamp() * 1e9)
    return timestamp


# Unix timestamp(ns) 转 datetime
def timestamp2datetime(timestamp):
    dateT = datetime.datetime.fromtimestamp(timestamp * 1e-9)
    return dateT


if __name__ == "__main__":
    ts_1 = 1627611933805260032
    gps_2 = [2168, 440979.599999999977]

    print(gps2cal(gps_2))
    print(datetime2cal(timestamp2datetime(ts_1)))
